package org.example.io.protocol.packet;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import org.example.io.protocol.Command;
import org.example.io.protocol.Packet;
import org.example.io.protocol.Serializer;
import org.example.io.protocol.serializer.JSONSerializer;

import java.util.HashMap;
import java.util.Map;

public class PacketCodec {

    public static final Integer MAGIC_NUMBER = 0x12345678;

    public static final PacketCodec INSTANCE = new PacketCodec();

    private final Map<Byte, Class<? extends Packet>> packetTypeMap;

    private final Map<Byte, Serializer> serializerMap;

    private PacketCodec() {
        packetTypeMap = new HashMap<>();
        packetTypeMap.put(Command.LOGIN_REQUEST, LoginRequestPacket.class);
        packetTypeMap.put(Command.LOGIN_RESPONSE, LoginResponsePacket.class);
        packetTypeMap.put(Command.MESSAGE_REQUEST, MessageRequestPacket.class);
        packetTypeMap.put(Command.MESSAGE_RESPONSE, MessageResponsePacket.class);
        packetTypeMap.put(Command.CREATEGROUP_REQUEST, CreateGroupRequestPacket.class);
        packetTypeMap.put(Command.CREATEGROUP_RESPONSE, CreateGroupResponsePacket.class);
//        packetTypeMap.put(Command.JOINGROUP_REQUEST, MessageResponsePacket.class);
//        packetTypeMap.put(Command.JOINGROUP_RESPONSE, MessageResponsePacket.class);
//        packetTypeMap.put(Command.QUITGROUP_REQUEST, MessageResponsePacket.class);
//        packetTypeMap.put(Command.QUITGROUP_RESPONSE, MessageResponsePacket.class);

        serializerMap = new HashMap<>();
        JSONSerializer jsonSerializer = new JSONSerializer();
        serializerMap.put(jsonSerializer.getSerializerAlgorithm(),jsonSerializer);
    }

    public ByteBuf encode(Packet packet) {
        // 尽可能创建一个直接内存
        ByteBuf byteBuf = ByteBufAllocator.DEFAULT.ioBuffer();
        byteBuf.writeInt(MAGIC_NUMBER);
        byteBuf.writeByte(Packet.version);
        // 序列化算法
        byteBuf.writeByte(Serializer.DEFAULT.getSerializerAlgorithm());
        // 指令
        byteBuf.writeByte(packet.getCommand());
        byte[] contents = Serializer.DEFAULT.serialize(packet);
        byteBuf.writeInt(contents.length);
        byteBuf.writeBytes(contents);
        return byteBuf;
    }

    public Packet decode(ByteBuf buf) {
        // 跳过魔数
        buf.skipBytes(4);
        // 跳过版本
        buf.skipBytes(1);
        // 跳过序列化算法
        buf.skipBytes(1);

        // 指令
        byte command = buf.readByte();
        // 长度
        int length = buf.readInt();
        byte[] contents = new byte[length];
        buf.readBytes(contents);

        Class<? extends Packet> packetClass = getRequestType(command);
        Serializer serializer = serializerMap.get(Serializer.DEFAULT.getSerializerAlgorithm());
        if (serializer != null) {
            return serializer.deserialize(packetClass, contents);
        }
        return null;
    }

    private Class<? extends Packet> getRequestType(Byte command) {
        return packetTypeMap.get(command);
    }

    public void printCommand() {
        StringBuffer sb = new StringBuffer();
        sb.append("登录：1");
        sb.append("发消息：1");
    }
}
